package com.ebo.storage.redis;

import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;

import redis.clients.jedis.Jedis;
import redis.clients.util.Pool;

import java.util.Date;

public class ShardedRedisPool extends Pool<Jedis> {

    private RedisShardInfo shard;

    public String getShardName() {
        return shard.getShardName();
    }

    public ShardedRedisPool(GenericObjectPool.Config poolConfig, RedisShardInfo redisShardInfo, String password) {
        super(poolConfig, new ShardedJedisFactory(redisShardInfo, password));
        this.shard = redisShardInfo;
    }

    /**
     * PoolableObjectFactory custom impl.
     */
    private static class ShardedJedisFactory extends BasePoolableObjectFactory<Object> {
        private RedisShardInfo redisShardInfo;
        private String pwd;

        public ShardedJedisFactory(RedisShardInfo redisShardInfo, String pwd) {
            this.redisShardInfo = redisShardInfo;
            this.pwd = pwd;
        }

        public Object makeObject() throws Exception {
            Jedis jedis = new Jedis(redisShardInfo.getMasterHost(), redisShardInfo.getMasterPort(), redisShardInfo.getTimeout());
            if (!pwd.equals("nopassword"))
                jedis.auth(pwd);
            return jedis;
        }

        public void destroyObject(final Object obj) throws Exception {
            if (obj instanceof Jedis) {
                Jedis jedis = (Jedis) obj;
                try {
                    jedis.disconnect();
//                    jedis.quit();
                } catch (Exception e) {
                    System.out.println(new Date().toString() + " redis关闭失败");
                    jedis.disconnect();
                }
            }
        }

        public boolean validateObject(final Object obj) {
            try {
                Jedis jedis = (Jedis) obj;
                return jedis.ping().equals("PONG");
            } catch (Exception ex) {
                ex.printStackTrace();
                return false;
            }
        }
    }

    public int getNumActive() {
        return internalPool.getNumActive();
    }

    public int getNumIdle() {
        return internalPool.getNumIdle();
    }

    public String getIp() {
        return this.shard.getMasterHost();
    }

}
